// ========================
// === Global variables ===
// ========================
#let 字号 = (
  初号: 42pt,
  小初: 36pt,
  一号: 26pt,
  小一: 24pt,
  二号: 22pt,
  小二: 18pt,
  三号: 16pt,
  小三: 15pt,
  四号: 14pt,
  中四: 13pt,
  小四: 12pt,
  五号: 10.5pt,
  小五: 9pt,
  六号: 7.5pt,
  小六: 6.5pt,
  七号: 5.5pt,
  小七: 5pt,
)

#let 字体 = (
  // 仿宋: ("Times New Roman", "FangSong"),
  宋体: ("Times New Roman", "SimSun"),
  黑体: ("Times New Roman", "SimHei"),
  // 楷体: ("Times New Roman", "KaiTi"),
  // 代码: ("New Computer Modern Mono", "Times New Roman", "SimSun"),
)

#let counter-page = counter(page)
#let stroke = 0.02857em


// ==================
// === Components ===
// ==================

#let cover(id-school, title-cn, title-en, author, affiliation, major, teacher-big, teacher-small, year, month, day) = {
  set align(center)
  set par(leading: 1em)
  let brown = rgb("#872d26")

  {
    set text(size: 字号.四号)
    set par(leading: 20pt, first-line-indent: 0em)

    grid(
      columns: (50%, 50%),
      align(left, box[
        #set align(left)

        #text(font: 字体.宋体, stroke: stroke + brown)[分类号：]

        #text(font: 字体.宋体, stroke: stroke + brown)[密#h(1em)级：]
        #text(font: 字体.黑体, stroke: stroke)[公开]
      ]),
      align(right, box[
        #set align(left)

        #text(font: 字体.宋体, stroke: stroke + brown)[单位代码：10422]

        #text(font: 字体.宋体, stroke: stroke + brown)[学#h(2em)号：]
        #text(font: 字体.宋体, stroke: stroke, id-school)
      ])
    )
  }
  v(1em)
  {
    set text(size: 字号.三号)

    image("cover.png", width: 100%)
    v(-1em)
    text(font: 字体.黑体, size: 字号.三号, fill: brown)[（专业学位）]
    linebreak()
    text(font: 字体.宋体, size: 字号.小二, stroke: stroke + brown)[论文题目：]
    text(font: 字体.黑体, size: 字号.小二, stroke: stroke, title-cn)
    linebreak()
    text(font: 字体.宋体, size: 字号.小二, stroke: stroke, title-en)
  }
  v(2em)
  {
    set text(size: 字号.四号)

    let fieldkey(key) = {
      let temp = ()
      for c in key {
        temp.push(c)
      }
      key = temp.join([#h(1em)])
      text(font: 字体.宋体, stroke: stroke + brown, key)
    }

    let fieldvalue(value) = {
      let temp = ()
      for c in value {
        temp.push(c)
      }
      value = temp.join(" ")
      grid(
        rows: (auto, auto),
        row-gutter: 0.6em,
        text(font: 字体.黑体, stroke: stroke, value),
        line(length: 100%, stroke: 1pt + brown)
      )
    }

    grid(
      columns: (130pt, 155pt),
      row-gutter: 1.5em,

      fieldkey("作者姓名"), fieldvalue(author),

      fieldkey("培养单位"), fieldvalue(affiliation),

      fieldkey("专业名称"), fieldvalue(major),

      fieldkey("指导教师"), fieldvalue(teacher-big),

      fieldkey("合作导师"), fieldvalue(teacher-small),
    )
  }
  v(1em)
  {
    set text(size: 字号.小二)
    text(font: 字体.黑体, stroke: stroke, year + h(1em))
    text(font: 字体.宋体, stroke: stroke + brown)[年#h(1em)]
    text(font: 字体.黑体, stroke: stroke, month + h(1em))
    text(font: 字体.宋体, stroke: stroke + brown)[月#h(1em)]
    text(font: 字体.黑体, stroke: stroke, day + h(1em))
    text(font: 字体.宋体, stroke: stroke + brown)[日]
  }

  pagebreak(weak: true)
}


#let announcement() = {
  set text(font: 字体.宋体)

  let utils-mapper = (x) => {
    x
    "_" * 9
    h(1em)
  }

  align(center, text(size: 字号.三号,
    "原 创 性 声 明"
  ))

  {
    set text(size: 字号.四号)
    set par(leading: 1em, first-line-indent: 2em, justify: true)
    [本人郑重声明：所呈交的学位论文，是本人在导师的指导下，独立进行研究所取得的成果。除文中已经注明引用的内容外，本论文不包含任何其他个人或集体已经发表或撰写过的科研成果。对本文的研究作出重要贡献的个人和集体，均已在文中以明确方式标明。本声明的法律责任由本人承担。]
    v(1em)
    align(center, grid(
      columns: 3,
      utils-mapper("论文作者签名："), h(3em), utils-mapper("日期：")
    ))
  }

  v(15em)

  align(center, text(size: 字号.三号,
    "关于学位论文使用授权的声明"
  ))

  {
    set text(size: 字号.四号)
    set par(leading: 1em, first-line-indent: 2em, justify: true)
    [
      本人同意学校保留或向国家有关部门或机构送交论文的印刷件和电子版，允许论文被查阅和借阅；本人授权山东大学可以将本学位论文的全部或部分内容编入有关数据库进行检索，可以采用影印、缩印或其他复制手段保存论文和汇编本学位论文。

      (保密论文在解密后应遵守此规定)
    ]
    v(1em)
    align(right, grid(
      columns: 3,
      ..([论文作者签名：], [导师签名：], [日  期：]).map(utils-mapper)
    ))
  }

  pagebreak(weak: true)
}


#let abstract-cn(abstract-cn-doc, abstract-cn-keywords) = {
  counter-page.update(1)

  heading(numbering: none, level: 1, outlined: true, [摘#h(2em)要])

  {
    set par(leading: 1em, justify: true)
    set text(font: 字体.宋体, size: 字号.小四)
    {
      set par(first-line-indent: 2em)
      abstract-cn-doc
    }
    {
      text(stroke: stroke)[关键词：]
      abstract-cn-keywords
    }
  }

  pagebreak(weak: true)
}


#let abstract-en(abstract-en-doc, abstract-en-keywords) = {
  heading(numbering: none, level: 1, outlined: true, [ABSTRACT])

  {
    set par(leading: 1em, justify: true)
    set text(font: 字体.宋体, size: 字号.小四)
    {
      set par(first-line-indent: 2em)
      abstract-en-doc
    }
    {
      text(stroke: stroke)[Key words:]
      abstract-en-keywords
    }
  }

  pagebreak(weak: true)
}


#let main(
  id-school: "",
  title-cn: "",
  title-en: "",
  author: "",
  affiliation: "",
  major: "",
  teacher-big: "",
  teacher-small: "",
  year: "",
  month: "",
  day: "",
  abstract-cn-doc: [],
  abstract-cn-keywords: [],
  abstract-en-doc: [],
  abstract-en-keywords: [],
  doc
  ) = {
  set page(
    paper: "a4",
    margin: (top: 2.8cm, bottom: 2.5cm, left: 2.5cm, right: 2.5cm),
  )
  set align(top)
  set text(lang: "zh")

  set heading(numbering: "1.1.1")
  show heading: it => {
    set par(leading: 1em, justify: true, first-line-indent: 0em)

    if it.level == 1 {
      counter(math.equation).update(0)
      counter(figure.where(kind: image)).update(0)
      counter(figure.where(kind: table)).update(0)
      counter(figure.where(kind: "code")).update(0)
      pagebreak(weak: true)

      v(24pt)
      align(center, text(font: 字体.黑体, size: 字号.小三, stroke: stroke,
        box(it)
      ))
      v(18pt)
    } else if it.level == 2 {
      v(24pt)
      align(left, text(font: 字体.黑体, size: 字号.四号, stroke: stroke,
        box(it)
      ))
      v(6pt)
    } else if it.level == 3 {
      v(12pt)
      align(left, text(font: 字体.黑体, size: 字号.小四, stroke: stroke,
        box(it)
      ))
      v(6pt)
    }
  }

  show outline: it => {
    set par(leading: 1em)
    set text(font: 字体.宋体, size: 字号.小四)
    it
  }
  let to-string(content) = {
    if content.has("text") {
      content.text
    } else if content.has("children") {
      content.children.map(to-string).join("")
    } else if content.has("body") {
      to-string(content.body)
    } else if content == [ ] {
      " "
    }
  }
  show outline.entry.where(level: 1): it => {
    [#to-string(it.body)#box(width: 1fr, it.fill)#it.page]
  }

  show figure.where(kind: table): set figure.caption(position: top)
  set figure(
    numbering: num => {
      let c = counter(heading).get()
      c = (c.at(0),)
      (c + (num,)).map(str).join("-")
    }
  )
  show figure.caption: it => {
    let caption = to-string(it.body).trim().split(" ")
    let projector = (
      "图": "Fig.",
      "表": "Tab.",
      "代码": "Code"
    )
    [
      #it.supplement
      #it.counter.display()
      #caption.at(0)

      #projector.at(to-string(it.supplement))
      #it.counter.display()
      #caption.at(1)
    ]
  }
  show figure: it => {
    set align(center)
    set text(字号.五号)
    let result = none
    if not it.has("kind") {
      it
    } else if it.kind == image {
      result = box(
        [
          #it.body
          #it.caption
        ]
      )
    } else if it.kind == table {
      result = box(
        [
          #it.caption
          #it.body
        ]
      )
    } else if it.kind == "code" {
      result = box(
        [
          代码#it.caption
          #it.body
        ]
      )
    }
    // block(result, width: 100%, above: 1em, below: 1em)
    result
  }

  // Ref: https://github.com/typst/typst/issues/1896#issuecomment-2005782054
  set math.equation(
    numbering: num => {
      let c = counter(heading).get()
      c = (c.at(0),)
      "(" + (c + (num,)).map(str).join("-") + ")"
    }
  )

  cover(id-school, title-cn, title-en, author, affiliation, major, teacher-big, teacher-small, year, month, day)
  announcement()

  {
    set page(header: {
      set align(center)
      set text(font: 字体.宋体, size: 字号.五号)
      [山东大学硕士学位论文]
      v(-1em)
      line(length: 100%, stroke: 1pt)
    })
    {
      set page(
        footer: {
          set align(center)
          set text(font: 字体.宋体, size: 字号.五号)
          counter-page.display("I")
          // counter-page.display()
        },
        numbering: "I"
      )
      abstract-cn(abstract-cn-doc, abstract-cn-keywords)
      abstract-en(abstract-en-doc, abstract-en-keywords)
      outline(title: [目#h(2em)录], indent: 2em, depth: 3)
    }
    {
      set page(
        footer: {
          set align(center)
          set text(font: 字体.宋体, size: 字号.五号)
          counter-page.display("1")
        },
        numbering: "1"
      )
      counter-page.update(1)
      set par(leading: 1em, justify: true, first-line-indent: 2em)
      set text(font: 字体.宋体, size: 字号.小四)

      doc
    }
  }
}
